package com.cliff.joinus;

import java.io.IOException;

import com.androidquery.callback.AjaxCallback;
import com.androidquery.callback.BitmapAjaxCallback;
import com.cliff.joinus.service.RendererService;

import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.MulticastLock;
import android.util.Log;

public class MainApplication extends Application {

	protected String TAG = "MainApplication";
	protected boolean WLAN_ONLY = true;
	
	protected BroadcastReceiver mReceiver = null;
	protected MicroHTTPD mHttpd = null;	
	protected MulticastLock multicastLock = null;
	protected boolean networkConnected = false;
	protected boolean inited = false;

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Context context = getApplicationContext();
		JoinusControlPoint.getInstance().setContext(context);
		LocalMediaDataManager.getInstance().setContext(context);

		initAQuery();
		super.onCreate();
	}
	
	@Override
	public void onLowMemory() {

		// clear all memory cached images when system is in low memory
		// note that you can configure the max image cache count, see
		// CONFIGURATION
		BitmapAjaxCallback.clearCache();
	}
	
	public void initAQuery() {		
		// set the max number of concurrent network connections, default is 4
		AjaxCallback.setNetworkLimit(2);

		// set the max number of icons (image width <= 50) to be cached in
		// memory, default is 20
		//BitmapAjaxCallback.setIconCacheLimit(20);

		// set the max number of images (image width > 50) to be cached in
		// memory, default is 20
		//BitmapAjaxCallback.setCacheLimit(50);

		// set the max size of an image to be cached in memory, default is 1600
		// pixels (ie. 400x400)
		//BitmapAjaxCallback.setPixelLimit(400 * 400);

		// set the max size of the memory cache, default is 1M pixels (4MB)
		//BitmapAjaxCallback.setMaxPixelLimit(1000000);
	}
	
	public void initService() {
		Log.d(TAG, "initService()");

		this.getApplicationContext().startService(new Intent(this, RendererService.class));		
	}
	
	public void uninitService() {
		Log.d(TAG, "uninitService()");

		this.getApplicationContext().stopService(new Intent(this, RendererService.class));				
	}

	public void init() {
		Log.d(TAG, "init()");

		if (inited)
			return;				
		inited = true;

		WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
		multicastLock = wifiManager.createMulticastLock(Constants.MULTICAST_LOCK);
		multicastLock.acquire();
		
		networkConnected = isNetworkConnected();

		registerNetworkBroadcastReceiver();
		LocalMediaDataManager.getInstance().updateLocalMediaList();
		
		if (networkConnected)
			JoinusControlPoint.getInstance().startAtBackground();

		try {
			mHttpd = new MicroHTTPD();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
//		initService();
	}
	
	public void uninit() {
		Log.d(TAG, "uninit()");		

		unregisterNetworkBroadcastReceiver();
		JoinusControlPoint.getInstance().stopAtBackground();
		multicastLock.release();
		
		if (null != mHttpd)
			mHttpd.stop();
		mHttpd = null;
		inited = false;
		
//		uninitService();
	}

	protected void restartControlPoint() {
		Log.d(TAG, "restartControlPoint():supposed not to be called, should check error here");		
		JoinusControlPoint.getInstance().stopAtBackground();
		JoinusControlPoint.getInstance().startAtBackground();
	}

	protected boolean isNetworkConnected() {
		boolean ret = false;
		ConnectivityManager cm = (ConnectivityManager) getApplicationContext()
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo ni = cm.getActiveNetworkInfo();
		if (null != ni) {
			if (WLAN_ONLY) {
				int TYPE_ETHERNET = 0x9; // for android 2.2/2.3
				if ((ConnectivityManager.TYPE_WIFI == ni.getType())
						|| (TYPE_ETHERNET == ni.getType())) {
					ret = ni.isConnected();
				}
			} else {				
				ret = ni.isConnected();
			}
		}

		Log.d(TAG, "isNetworkConnected():ret="+ret);
		return ret;
	}

	protected void registerNetworkBroadcastReceiver() {
		if (null != mReceiver)
			return;
		IntentFilter filter = new IntentFilter(
				ConnectivityManager.CONNECTIVITY_ACTION);
		mReceiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				boolean currentNetworkStatus = isNetworkConnected();
				if (currentNetworkStatus == networkConnected)
					return;
				
				networkConnected = currentNetworkStatus;
				if (networkConnected) {
					if (JoinusControlPoint.getInstance().isRunning())
						restartControlPoint();	//some logical error must occur when this line called
					else
						JoinusControlPoint.getInstance().startAtBackground();
				} else
					JoinusControlPoint.getInstance().stopAtBackground();
			}
		};
		getApplicationContext().registerReceiver(mReceiver, filter);
		return;
	}

	protected void unregisterNetworkBroadcastReceiver() {
		if (null != mReceiver) {
			getApplicationContext().unregisterReceiver(mReceiver);
			mReceiver = null;
		}
	}
	
	public boolean isHttpdRunning() {
		return (null != mHttpd);
	}

	public String getSSIDName() {
		Context context = getApplicationContext();
		WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
		WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
		String ret = wifiInfo.getSSID();
		return ((null == ret)?context.getString(R.string.hint_none):ret);
	}
	
}
